//
//  EQUtil.swift
//  DSP
//
//  Created by tucici on 2024/5/30.
//

import UIKit
let F_MAX = 20000.0
let F_MIN = 20.0
///基准频率
let F = 48000.0
///采样率
let R = 6.283185307179586
class EQUtil : NSObject {
    
    /// 把频率值，映射到某个线性范围内的整数值上。
    /// - Parameters:
    ///   - frency: 频率
    ///   - width: 相位画布的宽度，即范围
    /// - Returns: 映射后的整数
    class func toInt(frency:CGFloat, in width:CGFloat)->Double{
        let f = log10(22000.0) - log10(20.0)
        let f1 =  log10(frency) - log10(20.0)
        let result = f1 / f * width
        return result
    }
    
    /// 把线性范围内的整数值，映射到频率上<具体来说，它的功能是将一个线性范围内的整数值转换成一个对数范围内的频率值>
    /// - Parameters:
    ///   - v: 需要映射的值
    ///   - v_max: 整数线性范围的最大值
    ///   - v_min: 整数线性范围的最小值
    /// - Returns: 频率
    class func deInt(v:Int, inMax v_max:Int, inMin v_min:Int, f_max:Double=22000.0)->Double{
        let s_v = Double(v - v_min) / Double(v_max - v_min)
        let f = Double(log10(f_max) - log10(20.0))
        let result = pow(10.0, s_v * f + log10(20.0))
        return Double(result)
    }
    
    
    
    /// PEQ特性点增益值算法 <这个方法的目的是根据给定的 Q 值、增益和频率，计算一组滤波器系数，并将结果存储在 eqValue 数组中。这个过程通常用于音频处理，特别是参数均衡器的设计和实现。参数均衡器可以调整音频信号的频率响应，从而达到增强或衰减特定频率成分的效果。>
    /// - Parameters:
    ///   - quality: 表示滤波器的品质因数。Q值越高，带宽越窄，滤波器越尖锐
    ///   - gain: 增益，表示滤波器的增益或衰减值。单位通常为dB（分贝）
    ///   - frency: 频率，表示滤波器的中心频率，单位通常为Hz。
    ///   - array: 一个可变数组，用于存储计算后的均衡器系数。
    class func eq(quality:CGFloat, gain:CGFloat, frency:CGFloat, in array:inout [Double]){
        
        ///1。计算指数
        ///在音频处理和滤波器设计中，增益通常以分贝（dB）为单位表示。
        ///分贝是一个对数单位，用于表示两个值之间的比例。
        ///在这种情况下，我们需要将分贝转换为一个线性比例，以便用于滤波器系数的计算。
        ///公式 pow(10.0, gain / 40.0) 是将分贝转换为线性比例的一种方法。具体来说：
        ///如果 gain 是正数，var0 会大于 1，表示信号的放大。
        ///如果 gain 是负数，var0 会小于 1，表示信号的衰减。
        ///如果 gain 为 0，var0 等于 1，表示信号不变。
        let var0 = pow(10.0, (gain / 40.0))
        
        ///2。表示归一化的角频率，单位是弧度。
        ///它表示给定频率的角频率在采样频率下的比例。
        let var1 = R * frency / F
        
        ///3。通常用于表示滤波器的带宽。
        ///带宽越窄，滤波器的选择性越强。
        let var2 = sin(var1) / (2 * quality)
        let var3 = var2 / var0
        let var4 = -2.0 * cos(var1)
        let var5 = 1.0 - var2 / var0
        let var6 = -(2.0 * cos(var1)) * 1.0
        let var7 = (1.0 - var2 * var0) * 1.0
        let negVar6 = -var6
        let negVar4 = -var4
        
        for i in 0..<array.count {
            let f = deInt(v: i, inMax: array.count, inMin: 0)
            let var10 = R * f / F
            let cosVar10 = cos(var10)
            let cos2Var10 = cos(2.0 * var10)
            let sinVar10 = sin(var10)
            let sin2Var10 = sin(2.0 * var10)
            
            // 定义并计算中间变量
            let term1 = cosVar10 * var6 + (1.0 + var2 * var0) * 1.0 + cos2Var10 * var7
            let term2 = negVar6 * sinVar10 - sin2Var10 * var7
            let term3 = cosVar10 * var4 + 1.0 + var3 + cos2Var10 * var5
            let term4 = negVar4 * sinVar10 - sin2Var10 * var5
            
            // 计算分子和分母的平方和
            let numerator = pow(term1, 2.0) + pow(term2, 2.0)
            let denominator = pow(term3, 2.0) + pow(term4, 2.0)
            
            // 计算平方根
            let sqrtValue = sqrt(numerator / denominator)
            array[i] = log10(sqrtValue)
        }
    }
    
    /// 计算滤波器的相位响应或幅值响应，并将结果存储在`one`数组中。
    /// </这个方法主要用于计算滤波器的相位响应或幅值响应。具体来说，根据布尔值 ispol 的不同，该方法在两个模式之间切换：>
    /// </相位响应计算（当 ispol 为 true）：计算给定频率范围内滤波器的相位响应，并以度数形式存储在输出数组中。>
    ///</幅值响应计算（当 ispol 为 false）：计算给定频率范围内滤波器的幅值响应，并以对数形式存储在输出数组中。>
    /// - Parameters:
    ///   - a: 滤波器系数数组，用于分母多项式。
    ///   - b: 滤波器系数数组，用于分子多项式。
    ///   - one: 输出数组，用于存储计算结果。
    ///   - ispol: 布尔值，决定计算相位响应（true）还是幅值响应（false）。
    private class func mk(a: [Double], b: [Double], one: inout [Double], ispol: Bool) {
        let len = one.count
        var x, w, u, v, s, t, h: Double
        
        for i in 0..<len {
            // 计算频率
            x = deInt(v: i, inMax: len, inMin: 0, f_max: F_MAX)
            // 计算角频率
            w = 2 * Double.pi * x / F
            
            // 计算u和v（复数的实部和虚部）
            u = b[0] + b[1] * cos(w) + b[2] * cos(2 * w)
            v = -b[1] * sin(w) - b[2] * sin(2 * w)
            
            // 计算s和t（复数的实部和虚部）
            s = a[0] + a[1] * cos(w) + a[2] * cos(2 * w)
            t = -a[1] * sin(w) - a[2] * sin(2 * w)
            
            if ispol{
                // 计算复数的幅角
                let Im = (s * v - t * u)
                let Re = (s * u + t * v)
                
                // 计算相位角度并转换为度数
                h = 180 * atan2(Im, Re) / Double.pi
            }else{
                // 计算幅值
                h = sqrt((pow(u, 2) + pow(v, 2)) / (pow(s, 2) + pow(t, 2)))
                ///（对数幅值）
                h = log10(h)
            }
            
            // 存储结果
            one[i] = h
        }
    }
    
    private class func getArray(_ count:Int)->[Double]{
        return Array(repeating: 0.0, count: count)
    }
    
    /// 滤波算法
    /// - Parameters:
    ///   - f: 截止频率
    ///   - oct_type: 滤波类型
    ///   - ishpass: 高通 ｜ 低通
    ///   - bypass : 是否直通
    ///   - array: 数据源
    class func filter(f:Double, oct_type:Int, ishpass:Bool, bypass:Bool, array:inout [Double]){
        var p = getArray(4)
        var a0 = getArray(3)
        var a1 = getArray(3)
        var a2 = getArray(3)
        var a3 = getArray(3)
        var b0 = getArray(3)
        var b1 = getArray(3)
        var b2 = getArray(3)
        var b3 = getArray(3)
        
        // 计算角频率
        let w0 = 2 * Double.pi * f / F
        let oc = 2 * tan(w0 / 2)
        let c1 = oc * tan(w0 / 2)
        
        let iszero = (f == F_MAX && !ishpass) || (f == F_MIN && ishpass) || bypass
        if iszero {
            array = getArray(array.count)
            return
        }
        switch oct_type{
        case 0://BW-06
            p[0] = ishpass ? 1 : 0
            
            a0[0] = ishpass ? 1 : 1
            a0[1] = ishpass ? ((c1 - p[0] * oc) / (c1 + p[0] * oc)) : (oc - 2) / (oc + 2)
            a0[2] = ishpass ? 0 : 0
            
            b0[0] = ishpass ? (oc / (c1 + p[0] * oc)) : oc / (2 + oc)
            b0[1] = ishpass ? -b0[0] : b0[0]
            b0[2] = ishpass ? 0 : 0
            
            var one_0 = getArray(array.count)
            mk(a: a0, b: b0, one: &one_0, ispol: false)
            array = iszero ? getArray(array.count) :one_0
        case 1:// BW-12
            p[0] = ishpass ? 1.41421356237309 : 1.41421356237309
            
            a0[0] = ishpass ? 1 : 1
            a0[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : 2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc)
            a0[2] = ishpass ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc)
            
            b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : oc * oc / (4 + 2 * p[0] * oc + oc * oc)
            b0[1] = ishpass ? -2 * b0[0] : 2 * b0[0]
            b0[2] = ishpass ? b0[0] : b0[0]
            
            var one_0 = getArray(array.count)
            mk(a: a0, b: b0, one: &one_0, ispol: false)
            array = iszero ? getArray(array.count) : one_0
        case 2://BW-18
            p[0] = ishpass ? 1 : 1
            p[1] = ishpass ? 1 : 1
            
            a0[0] = ishpass ? 1 : 1
            a0[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc))
            a0[2] = ishpass ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc))
            
            a1[0] = ishpass ? 1 : 1
            a1[1] = ishpass ? (-(p[1] * oc - c1) / (c1 + p[1] * oc)) : ((p[1] * oc - 2) / (2 + p[1] * oc))
            a1[2] = ishpass ? 0 : 0
            
            b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc))
            b0[1] = ishpass ? -2 * b0[0] : (2 * b0[0])
            b0[2] = ishpass ? b0[0] : b0[0]
            
            b1[0] = ishpass ? (p[1] * oc / (c1 + p[1] * oc)) : (p[1] * oc / (2 + p[1] * oc))
            b1[1] = ishpass ? -b1[0] : b1[0]
            b1[2] = ishpass ? 0 : 0
            
            var one_0 = getArray(array.count)
            var one_1 = getArray(array.count)
            mk(a: a0, b: b0, one: &one_0, ispol: false)
            mk(a: a1, b: b1, one: &one_1, ispol: false)
            array = iszero ? getArray(array.count) : zip(one_0,one_1).map{$0+$1}
        case 3://BW-24
            p[0] = ishpass ? 0.76536686473018 : 0.76536686473018
            p[1] = ishpass ? 1.84775906502257 : 1.84775906502257
            
            a0[0] = ishpass ? 1 : 1
            a0[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc))
            a0[2] = ishpass ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc))
            
            a1[0] = ishpass ? 1 : 1
            a1[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[1] * oc + oc * oc))
            a1[2] = ishpass ? ((c1 * c1 - c1 * p[1] * oc + oc * oc) / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : ((4 - 2 * p[1] * oc + oc * oc) / (4 + 2 * p[1] * oc + oc * oc))
            
            b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc))
            b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0])
            b0[2] = ishpass ? b0[0] : b0[0]
            
            b1[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[1] * oc + oc * oc))
            b1[1] = ishpass ? (-2 * b1[0]) : (2 * b1[0])
            b1[2] = ishpass ? b1[0] : b1[0]
            
            var one_0 = getArray(array.count)
            var one_1 = getArray(array.count)
            mk(a: a0, b: b0, one: &one_0, ispol: false)
            mk(a: a1, b: b1, one: &one_1, ispol: false)
            array = iszero ? getArray(array.count) : zip(one_0,one_1).map{$0+$1}
        case 4://BW-36
            p[0] = ishpass ? 0.51763809020504 : 0.51763809020504
            p[1] = ishpass ? 1.41421356237309 : 1.41421356237309
            p[2] = ishpass ? 1.93185165257814 : 1.93185165257814
            
            a0[0] = ishpass ? 1 : 1
            a0[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc))
            a0[2] = ishpass ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc))
            
            a1[0] = ishpass ? 1 : 1
            a1[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[1] * oc + oc * oc))
            a1[2] = ishpass ? ((c1 * c1 - c1 * p[1] * oc + oc * oc) / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : ((4 - 2 * p[1] * oc + oc * oc) / (4 + 2 * p[1] * oc + oc * oc))
            
            a2[0] = ishpass ? 1 : 1
            a2[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[2] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[2] * oc + oc * oc))
            a2[2] = ishpass ? ((c1 * c1 - c1 * p[2] * oc + oc * oc) / (c1 * c1 + c1 * p[2] * oc + oc * oc)) : ((4 - 2 * p[2] * oc + oc * oc) / (4 + 2 * p[2] * oc + oc * oc))
            
            
            b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc))
            b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0])
            b0[2] = ishpass ? b0[0] : b0[0]
            
            
            b1[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[1] * oc + oc * oc))
            b1[1] = ishpass ? (-2 * b1[0]) : (2 * b1[0])
            b1[2] = ishpass ? b1[0] : b1[0]
            
            
            b2[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[2] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[2] * oc + oc * oc))
            b2[1] = ishpass ? (-2 * b2[0]) : (2 * b2[0])
            b2[2] = ishpass ? b2[0] : b2[0]
            
            var one_0 = getArray(array.count)
            var one_1 = getArray(array.count)
            var one_2 = getArray(array.count)
            mk(a: a0, b: b0, one: &one_0, ispol: false)
            mk(a: a1, b: b1, one: &one_1, ispol: false)
            mk(a: a2, b: b2, one: &one_2, ispol: false)
            array = iszero ? getArray(array.count) : zip(one_0,zip(one_1,one_2)).map{$0+$1.0+$1.1}
        case 5://BW-48
            p[0] = ishpass ? 0.39018064403226 : 0.39018064403226
            p[1] = ishpass ? 1.11114046603920 : 1.11114046603920
            p[2] = ishpass ? 1.66293922460509 : 1.66293922460509
            p[3] = ishpass ? 1.96157056080646 : 1.96157056080646
            
            a0[0] = ishpass ? 1 : 1
            a0[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc))
            a0[2] = ishpass ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc))
            
            a1[0] = ishpass ? 1 : 1
            a1[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[1] * oc + oc * oc))
            a1[2] = ishpass ? ((c1 * c1 - c1 * p[1] * oc + oc * oc) / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : ((4 - 2 * p[1] * oc + oc * oc) / (4 + 2 * p[1] * oc + oc * oc))
            
            a2[0] = ishpass ? 1 : 1
            a2[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[2] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[2] * oc + oc * oc))
            a2[2] = ishpass ? ((c1 * c1 - c1 * p[2] * oc + oc * oc) / (c1 * c1 + c1 * p[2] * oc + oc * oc)) : ((4 - 2 * p[2] * oc + oc * oc) / (4 + 2 * p[2] * oc + oc * oc))
            
            a3[0] = ishpass ? 1 : 1
            a3[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[3] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[3] * oc + oc * oc))
            a3[2] = ishpass ? ((c1 * c1 - c1 * p[3] * oc + oc * oc) / (c1 * c1 + c1 * p[3] * oc + oc * oc)) : ((4 - 2 * p[3] * oc + oc * oc) / (4 + 2 * p[3] * oc + oc * oc))
            
            b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc))
            b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0])
            b0[2] = ishpass ? b0[0] : b0[0]
            
            b1[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[1] * oc + oc * oc))
            b1[1] = ishpass ? (-2 * b1[0]) : (2 * b1[0])
            b1[2] = ishpass ? b1[0] : b1[0]
            
            b2[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[2] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[2] * oc + oc * oc))
            b2[1] = ishpass ? (-2 * b2[0]) : (2 * b2[0])
            b2[2] = ishpass ? b2[0] : b2[0]
            
            b3[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[3] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[3] * oc + oc * oc))
            b3[1] = ishpass ? (-2 * b3[0]) : (2 * b3[0])
            b3[2] = ishpass ? b3[0] : b3[0]
            
            var one_0 = getArray(array.count)
            var one_1 = getArray(array.count)
            var one_2 = getArray(array.count)
            var one_3 = getArray(array.count)
            mk(a: a0, b: b0, one: &one_0, ispol: false)
            mk(a: a1, b: b1, one: &one_1, ispol: false)
            mk(a: a2, b: b2, one: &one_2, ispol: false)
            mk(a: a3, b: b3, one: &one_3, ispol: false)
            array = iszero ? getArray(array.count) : zip(zip(one_0,one_1),zip(one_2,one_3)).map{$0.0+$0.1+$1.0+$1.1}
        case 6://BS-12
            p[0] = ishpass ? 1.73205080756888 : 1.73205080756888
            
            a0[0] = ishpass ? 1 : 1
            a0[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc))
            a0[2] = ishpass ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc))
            
            b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc))
            b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0])
            b0[2] = ishpass ? b0[0] : b0[0]
            
            var one_0 = getArray(array.count)
            mk(a: a0, b: b0, one: &one_0, ispol: false)
            array = iszero ? getArray(array.count) : one_0
        case 7://BS-18
            p[0] = ishpass ? 1.49128077169616 : 1.49128077169616
            p[1] = ishpass ? 0.94160002653321 : 0.94160002653321
            
            a0[0] = ishpass ? 1 : 1
            a0[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc))
            a0[2] = ishpass ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc))
            
            a1[0] = ishpass ? 1 : 1
            a1[1] = ishpass ? (-(p[1] * oc - c1) / (c1 + p[1] * oc)) : ((p[1] * oc - 2) / (2 + p[1] * oc))
            a1[2] = ishpass ? 0 : 0
            
            b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc))
            b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0])
            b0[2] = ishpass ? b0[0] : b0[0]
            
            b1[0] = ishpass ? (p[1] * oc / (c1 + p[1] * oc)) : (p[1] * oc / (2 + p[1] * oc))
            b1[1] = ishpass ? (-b1[0]) : b1[0]
            b1[2] = ishpass ? 0 : 0
            
            var one_0 = getArray(array.count)
            var one_1 = getArray(array.count)
            mk(a: a0, b: b0, one: &one_0, ispol: false)
            mk(a: a1, b: b1, one: &one_1, ispol: false)
            array = iszero ? getArray(array.count) : zip(one_0,one_1).map{$0+$1}
        case 8://BS-24
            p[0] = ishpass ? 1.31442234334377 : 1.31442234334377
            p[1] = ishpass ? 1.80951759357649 : 1.80951759357649
            
            a0[0] = ishpass ? 1 : 1
            a0[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc))
            a0[2] = ishpass ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc))
            
            a1[0] = ishpass ? 1 : 1
            a1[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[1] * oc + oc * oc))
            a1[2] = ishpass ? ((c1 * c1 - c1 * p[1] * oc + oc * oc) / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : ((4 - 2 * p[1] * oc + oc * oc) / (4 + 2 * p[1] * oc + oc * oc))
            
            b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc))
            b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0])
            b0[2] = ishpass ? b0[0] : b0[0]
            
            b1[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[1] * oc + oc * oc))
            b1[1] = ishpass ? (-2 * b1[0]) : (2 * b1[0])
            b1[2] = ishpass ? b1[0] : b1[0]
            
            var one_0 = getArray(array.count)
            var one_1 = getArray(array.count)
            mk(a: a0, b: b0, one: &one_0, ispol: false)
            mk(a: a1, b: b1, one: &one_1, ispol: false)
            array = iszero ? getArray(array.count) : zip(one_0,one_1).map{$0+$1}
        case 9://BS-36
            p[0] = ishpass ? 1.81878136609445 : 1.81878136609445
            p[1] = ishpass ? 1.59930837166566 : 1.59930837166566
            p[2] = ishpass ? 1.07710536333862 : 1.07710536333862
            
            a0[0] = ishpass ? 1 : 1
            a0[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc))
            a0[2] = ishpass ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc))
            
            a1[0] = ishpass ? 1 : 1
            a1[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[1] * oc + oc * oc))
            a1[2] = ishpass ? ((c1 * c1 - c1 * p[1] * oc + oc * oc) / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : ((4 - 2 * p[1] * oc + oc * oc) / (4 + 2 * p[1] * oc + oc * oc))
            
            a2[0] = ishpass ? 1 : 1
            a2[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[2] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[2] * oc + oc * oc))
            a2[2] = ishpass ? ((c1 * c1 - c1 * p[2] * oc + oc * oc) / (c1 * c1 + c1 * p[2] * oc + oc * oc)) : ((4 - 2 * p[2] * oc + oc * oc) / (4 + 2 * p[2] * oc + oc * oc))
            
            b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc))
            b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0])
            b0[2] = ishpass ? b0[0] : b0[0]
            
            b1[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[1] * oc + oc * oc))
            b1[1] = ishpass ? (-2 * b1[0]) : (2 * b1[0])
            b1[2] = ishpass ? b1[0] : b1[0]
            
            b2[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[2] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[2] * oc + oc * oc))
            b2[1] = ishpass ? (-2 * b2[0]) : (2 * b2[0])
            b2[2] = ishpass ? b2[0] : b2[0]
            
            var one_0 = getArray(array.count)
            var one_1 = getArray(array.count)
            var one_2 = getArray(array.count)
            mk(a: a0, b: b0, one: &one_0, ispol: false)
            mk(a: a1, b: b1, one: &one_1, ispol: false)
            mk(a: a2, b: b2, one: &one_2, ispol: false)
            array = iszero ? getArray(array.count) : zip(one_0,zip(one_1,one_2)).map{$0+$1.0+$1.1}
        case 10://BS-48
            p[0] = ishpass ? 1.81936630933058 : 1.81936630933058
            p[1] = ishpass ? 1.69465016047187 : 1.69465016047187
            p[2] = ishpass ? 1.42227636169708 : 1.42227636169708
            p[3] = ishpass ? 0.92434808250642 : 0.92434808250642
            
            a0[0] = ishpass ? 1 : 1
            a0[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc))
            a0[2] = ishpass ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc))
            
            a1[0] = ishpass ? 1 : 1
            a1[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[1] * oc + oc * oc))
            a1[2] = ishpass ? ((c1 * c1 - c1 * p[1] * oc + oc * oc) / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : ((4 - 2 * p[1] * oc + oc * oc) / (4 + 2 * p[1] * oc + oc * oc))
            
            a2[0] = ishpass ? 1 : 1
            a2[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[2] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[2] * oc + oc * oc))
            a2[2] = ishpass ? ((c1 * c1 - c1 * p[2] * oc + oc * oc) / (c1 * c1 + c1 * p[2] * oc + oc * oc)) : ((4 - 2 * p[2] * oc + oc * oc) / (4 + 2 * p[2] * oc + oc * oc))
            
            a3[0] = ishpass ? 1 : 1
            a3[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[3] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[3] * oc + oc * oc))
            a3[2] = ishpass ? ((c1 * c1 - c1 * p[3] * oc + oc * oc) / (c1 * c1 + c1 * p[3] * oc + oc * oc)) : ((4 - 2 * p[3] * oc + oc * oc) / (4 + 2 * p[3] * oc + oc * oc))
            
            b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc))
            b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0])
            b0[2] = ishpass ? b0[0] : b0[0]
            
            b1[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[1] * oc + oc * oc))
            b1[1] = ishpass ? (-2 * b1[0]) : (2 * b1[0])
            b1[2] = ishpass ? b1[0] : b1[0]
            
            b2[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[2] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[2] * oc + oc * oc))
            b2[1] = ishpass ? (-2 * b2[0]) : (2 * b2[0])
            b2[2] = ishpass ? b2[0] : b2[0]
            
            b3[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[3] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[3] * oc + oc * oc))
            b3[1] = ishpass ? (-2 * b3[0]) : (2 * b3[0])
            b3[2] = ishpass ? b3[0] : b3[0]
            
            var one_0 = getArray(array.count)
            var one_1 = getArray(array.count)
            var one_2 = getArray(array.count)
            var one_3 = getArray(array.count)
            mk(a: a0, b: b0, one: &one_0, ispol: false)
            mk(a: a1, b: b1, one: &one_1, ispol: false)
            mk(a: a2, b: b2, one: &one_2, ispol: false)
            mk(a: a3, b: b3, one: &one_3, ispol: false)
            array = iszero ? getArray(array.count) : zip(zip(one_0,one_1),zip(one_2,one_3)).map{$0.0+$0.1+$1.0+$1.1}
        case 11://LK-12
            a0[0] = ishpass ? 1 : 1
            a0[1] = ishpass ? (-(oc - c1) / (c1 + oc)) : ((oc - 2) / (2 + oc))
            a0[2] = ishpass ? 0 : 0
            
            a1[0] = ishpass ? a0[0] : a0[0]
            a1[1] = ishpass ? a0[1] : a0[1]
            a1[2] = ishpass ? a0[2] : a0[2]
            
            b0[0] = ishpass ? (oc / (c1 + oc)) : (oc / (2 + oc))
            b0[1] = ishpass ? (-b0[0]) : b0[0]
            b0[2] = ishpass ? 0 : 0
            
            b1[0] = ishpass ? b0[0] : b0[0]
            b1[1] = ishpass ? b0[1] : b0[1]
            b1[2] = ishpass ? b0[2] : b0[2]
            
            var one_0 = getArray(array.count)
            var one_1 = getArray(array.count)
            mk(a: a0, b: b0, one: &one_0, ispol: false)
            mk(a: a1, b: b1, one: &one_1, ispol: false)
            array = iszero ? getArray(array.count) : zip(one_0,one_1).map{$0+$1}
        case 12: //LK-24
            p[0] = ishpass ? 1.41421356237309 : 1.41421356237309
            
            a0[0] = ishpass ? 1 : 1
            a0[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc))
            a0[2] = ishpass ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc))
            
            a1[0] = ishpass ? a0[0] : a0[0]
            a1[1] = ishpass ? a0[1] : a0[1]
            a1[2] = ishpass ? a0[2] : a0[2]
            
            b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc))
            b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0])
            b0[2] = ishpass ? b0[0] : b0[0]
            
            b1[0] = ishpass ? b0[0] : b0[0]
            b1[1] = ishpass ? b0[1] : b0[1]
            b1[2] = ishpass ? b0[2] : b0[2]
            
            var one_0 = getArray(array.count)
            var one_1 = getArray(array.count)
            mk(a: a0, b: b0, one: &one_0, ispol: false)
            mk(a: a1, b: b1, one: &one_1, ispol: false)
            array = iszero ? getArray(array.count) : zip(one_0,one_1).map{$0+$1}
        case 13://LK-36
            p[0] = ishpass ? 0.76536686473018 : 0.76536686473018
            p[1] = ishpass ? 1.84775906502257 : 1.84775906502257
            p[2] = ishpass ? 1.41421356237309 : 1.41421356237309
            
            a0[0] = ishpass ? 1 : 1
            a0[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc))
            a0[2] = ishpass ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc))
            
            a1[0] = ishpass ? 1 : 1
            a1[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[1] * oc + oc * oc))
            a1[2] = ishpass ? ((c1 * c1 - c1 * p[1] * oc + oc * oc) / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : ((4 - 2 * p[1] * oc + oc * oc) / (4 + 2 * p[1] * oc + oc * oc))
            
            a2[0] = ishpass ? 1 : 1
            a2[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[2] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[2] * oc + oc * oc))
            a2[2] = ishpass ? ((c1 * c1 - c1 * p[2] * oc + oc * oc) / (c1 * c1 + c1 * p[2] * oc + oc * oc)) : ((4 - 2 * p[2] * oc + oc * oc) / (4 + 2 * p[2] * oc + oc * oc))
            
            b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc))
            b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0])
            b0[2] = ishpass ? b0[0] : b0[0]
            
            b1[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[1] * oc + oc * oc))
            b1[1] = ishpass ? (-2 * b1[0]) : (2 * b1[0])
            b1[2] = ishpass ? b1[0] : b1[0]
            
            b2[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[2] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[2] * oc + oc * oc))
            b2[1] = ishpass ? (-2 * b2[0]) : (2 * b2[0])
            b2[2] = ishpass ? b2[0] : b2[0]
            
            var one_0 = getArray(array.count)
            var one_1 = getArray(array.count)
            var one_2 = getArray(array.count)
            mk(a: a0, b: b0, one: &one_0, ispol: false)
            mk(a: a1, b: b1, one: &one_1, ispol: false)
            mk(a: a2, b: b2, one: &one_2, ispol: false)
            array = iszero ? getArray(array.count) : zip(one_0,zip(one_1,one_2)).map{$0+$1.0+$1.1}
        case 14://LK-48
            p[0] = ishpass ? 0.76536686473018 : 0.76536686473018
            p[1] = ishpass ? 1.84775906502257 : 1.84775906502257
            
            a0[0] = ishpass ? 1 : 1
            a0[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc))
            a0[2] = ishpass ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc))
            
            a1[0] = ishpass ? 1 : 1
            a1[1] = ishpass ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (2 * (oc * oc - 4) / (4 + 2 * p[1] * oc + oc * oc))
            a1[2] = ishpass ? ((c1 * c1 - c1 * p[1] * oc + oc * oc) / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : ((4 - 2 * p[1] * oc + oc * oc) / (4 + 2 * p[1] * oc + oc * oc))
            
            a2[0] = ishpass ? a0[0] : a0[0]
            a2[1] = ishpass ? a0[1] : a0[1]
            a2[2] = ishpass ? a0[2] : a0[2]
            
            a3[0] = ishpass ? a1[0] : a1[0]
            a3[1] = ishpass ? a1[1] : a1[1]
            a3[2] = ishpass ? a1[2] : a1[2]
            
            b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc))
            b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0])
            b0[2] = ishpass ? b0[0] : b0[0]
            
            b1[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[1] * oc + oc * oc))
            b1[1] = ishpass ? (-2 * b1[0]) : (2 * b1[0])
            b1[2] = ishpass ? b1[0] : b1[0]
            
            b2[0] = ishpass ? b0[0] : b0[0]
            b2[1] = ishpass ? b0[1] : b0[1]
            b2[2] = ishpass ? b0[2] : b0[2]
            
            b3[0] = ishpass ? b1[0] : b1[0]
            b3[1] = ishpass ? b1[1] : b1[1]
            b3[2] = ishpass ? b1[2] : b1[2]
            
            var one_0 = getArray(array.count)
            var one_1 = getArray(array.count)
            var one_2 = getArray(array.count)
            var one_3 = getArray(array.count)
            mk(a: a0, b: b0, one: &one_0, ispol: false)
            mk(a: a1, b: b1, one: &one_1, ispol: false)
            mk(a: a2, b: b2, one: &one_2, ispol: false)
            mk(a: a3, b: b3, one: &one_3, ispol: false)
            array = iszero ? getArray(array.count) : zip(zip(one_0,one_1),zip(one_2,one_3)).map{$0.0+$0.1+$1.0+$1.1}
        default:
            break
        }
    }
}
//"Slope dB/oct" 是一个常见的术语，用于描述滤波器的频率响应特性，特别是描述滤波器在截止频率之后的衰减速率。

//Slope：表示滤波器的斜率，即频率响应曲线在截止频率之后的变化速率。
//dB/oct：表示每倍频程（octave）内的衰减量，以分贝（dB）为单位。
//详细说明
//倍频程（Octave）：
//倍频程是频率的一个对数单位，表示频率加倍。例如，从 1000 Hz 到 2000 Hz 是一个倍频程，从 500 Hz 到 1000 Hz 也是一个倍频程。
//分贝（dB）：
//分贝是一个对数单位，用于描述信号强度的相对变化。它通常用于表示增益或衰减。
//具体例子
//假设我们有一个低通滤波器，其频率响应曲线的斜率是 -12 dB/oct。这意味着：
//在截止频率fc之后，每增加一个倍频程，信号的强度会衰减 12 分贝。
//如果截止频率fc为 1000 Hz，那么在 2000 Hz（一个倍频程之后）信号的强度会减少 12 分贝。
//在 4000 Hz（两个倍频程之后），信号的强度会减少 24 分贝（每个倍频程 12 分贝，共 2 个倍频程）。
//常见斜率
//-6 dB/oct：一阶滤波器的典型斜率（如简单的 RC 低通滤波器）。
//-12 dB/oct：二阶滤波器的典型斜率。
//-18 dB/oct：三阶滤波器的典型斜率。
//-24 dB/oct：四阶滤波器的典型斜率。
//总结
//"Slope dB/oct" 是描述滤波器频率响应特性的一个重要参数，表示在截止频率之后每增加一个倍频程，信号强度的衰减量。不同阶数的滤波器会有不同的斜率，这决定了它们在频域中的性能和应用场景。
